package main

import (
	"context"
	"getaway/basic/config"
	_ "getaway/basic/init"
	_ "getaway/docs"
	"getaway/router"
	"github.com/gin-gonic/gin"
	_ "github.com/share309/gojwt"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"log"
	"net/http"
	"net/http/pprof"
	"os"
	"os/signal"
	"runtime/trace"
	"syscall"
	"time"
)

// @title           滴滴打车
// @version         1.0
// @description     This is a sample server seller server.
// @termsOfService  http://swagger.io/terms/
// @contact.name   API Support
// @contact.url    http://www.swagger.io/support
// @contact.email  support@swagger.io
// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html
// @host  localhost:8888
// @BasePath  /v1
// @securityDefinitions.apikey TokenAuth
// @in header
// @name x-token
func main() {
	r := router.Router()
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	r.Static("/upload", config.FileWay)

	// 添加pprof路由到Gin
	r.GET("/debug/pprof", gin.WrapH(http.HandlerFunc(pprof.Index)))
	r.GET("/debug/pprof/cmdline", gin.WrapH(http.HandlerFunc(pprof.Cmdline)))
	r.GET("/debug/pprof/profile", gin.WrapH(http.HandlerFunc(pprof.Profile)))
	r.GET("/debug/pprof/symbol", gin.WrapH(http.HandlerFunc(pprof.Symbol)))
	r.GET("/debug/pprof/trace", gin.WrapH(http.HandlerFunc(pprof.Trace)))
	// 为goroutine, heap, threadcreate, block等添加路由
	r.GET("/debug/pprof/goroutine", gin.WrapH(http.HandlerFunc(pprof.Handler("goroutine").ServeHTTP)))
	r.GET("/debug/pprof/heap", gin.WrapH(http.HandlerFunc(pprof.Handler("heap").ServeHTTP)))
	r.GET("/debug/pprof/threadcreate", gin.WrapH(http.HandlerFunc(pprof.Handler("threadcreate").ServeHTTP)))
	r.GET("/debug/pprof/block", gin.WrapH(http.HandlerFunc(pprof.Handler("block").ServeHTTP)))

	// 添加自定义trace路由
	r.GET("/debug/trace", func(c *gin.Context) {
		c.Writer.Header().Set("Content-Type", "application/octet-stream")
		c.Writer.Header().Set("Content-Disposition", "attachment; filename=trace.out")
		trace.Start(c.Writer)
		defer trace.Stop()

		// 设置一个超时时间，防止trace文件过大
		timer := time.AfterFunc(10*time.Second, func() {
			trace.Stop()
		})
		defer timer.Stop()

		// 等待客户端断开连接或超时
		<-c.Writer.CloseNotify()
	})

	srv := &http.Server{
		Addr:    ":8888",
		Handler: r,
	}

	go func() {
		// service connections
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()

	// Wait for interrupt signal to gracefully shut down the server with
	// a timeout of 5 seconds.
	quit := make(chan os.Signal, 1)
	// kill (no params) by default sends syscall.SIGTERM
	// kill -2 is syscall.SIGINT
	// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	log.Println("Shutdown Server ...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Println("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}
